home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / utils / lack.zoo / trap2.c < prev    next >
C/C++ Source or Header  |  1994-01-01  |  16KB  |  592 lines

  1. #include "lack.h"
  2. #include "sysvars.h"
  3. #include "xbra.h"
  4. #include <string.h>
  5. #include <osbind.h>
  6. #include <mintbind.h>
  7.  
  8. lap *lapps[NUM_APPS];
  9. lap *curapp;
  10.  
  11. struct save_area
  12. {
  13.     int in_use;
  14.     long dregs[8];     /* These are gem's registers at the time of the
  15.                 * task switch.  User's registers are pushed onto
  16.                 * the usp. */
  17.     void (*stopped)(); /* Where the task switch was called from. */
  18.     long aregs[6];     /* a1-a6 as dregs */
  19.     void *g_ssp;       /* + 0x3e */
  20.     void *usp;       /* + 0x42 */
  21.     void *u_ssp;       /* + 0x46 */
  22. };
  23.  
  24. ki;
  25.  
  26. int in_aes;    /* are we servicing an aes call, rather than letting some apid run */
  27. int get_menu_title; /* let the controler acc's do menu_register? */
  28. int aes_active;     /* I don't know how to keep this thing up to date */
  29. int aes_version;
  30. struct save_area *apid0_save=NULL; /* test for wether apid 0 is the desktop, see below */
  31. struct appl *apid0_appl;      /*  "    "    " ...                                 */
  32. int is_desk=FALSE;
  33. static int first=TRUE;
  34. int apid;      /* the running application, to the best of my knowledge */
  35. int __desk_stk[1024];
  36. const long desk_stk=(long)&__desk_stk[1023];
  37. static void (*yield_aes)(void);
  38. void *os_base;
  39. /*void *os_end; I don't know how to set this */
  40.  
  41. struct global_action *gl_action;
  42.  
  43. /* in lack.s: */
  44. extern void trap_2(void);
  45. extern void trap_3(void);
  46. extern void trap_13(void);
  47. extern void _first_leave_aes(void);
  48. extern void _desk_leave_aes(void);
  49.  
  50. /* in jump.s: */
  51. extern int setjump(lap *);
  52. extern int longjump(lap *);
  53.  
  54. /* in wind.c: */
  55. extern void desk_zap_windows(void);
  56.  
  57. /* vectors to search down before unloading acc, the first nine spaces are for
  58.  * kbdvecs.
  59.  * Maybe I should add mfp ints, or save everything which doesn't have the high
  60.  * byte set.  It does not take much memory to save these things and refer back
  61.  * to them.
  62.  * If you add vectors leave off the cast, and the error message will tell you
  63.  * what NUM_VECS should be changed to.
  64.  */
  65. #define NUM_VECS 54
  66. char **vecs[NUM_VECS]={(char **)0x0, (char **)0x0, (char **)0x0, (char **)0x0, 
  67. (char **)0x0, (char **)0x0, (char **)0x0, (char **)0x0, (char **)0x0, 
  68. (char **)0x08, (char **)0x0c, (char **)0x10, (char **)0x14, (char **)0x18, 
  69. (char **)0x1c, (char **)0x20, (char **)0x24, (char **)0x2c, (char **)0x34, 
  70. (char **)0x38, (char **)0x3c, (char **)0x60, (char **)0x70, (char **)0x84, 
  71. (char **)0x88, (char **)0xb4, (char **)0xb8, (char **)0xc0, (char **)0xe0, 
  72. (char **)0xe4, (char **)0xe8, (char **)0x114, (char **)0x400, (char **)0x404, 
  73. (char **)0x408, (char **)0x42a, (char **)0x472, (char **)0x476, (char **)0x47e, 
  74. (char **)0x4f6, (char **)0x506, (char **)0x50a, (char **)0x50e, (char **)0x512, 
  75. (char **)0x51e, (char **)0x53e, (char **)0x55e, (char **)0x57e, (char **)0x108, 
  76. (char **)0x118, (char **)0x124, (char **)0x128, (char **)0x12c, (char **)0x130};
  77.  
  78. struct xbra gem=  {XBRA_MAGIC, 0x6c61636bL /*'lack'*/, NULL, JMP_OPCODE,
  79.            (void *)trap_2};
  80. struct xbra mytrap={XBRA_MAGIC, 0x6c61636bL /*'lack'*/, NULL, JMP_OPCODE,
  81.            (void *)trap_3};
  82. struct xbra bios= {XBRA_MAGIC, 0x6c61636bL /*'lack'*/, NULL, JMP_OPCODE,
  83.            (void *)trap_13};
  84. install_trap2()
  85. {
  86.     long ssp;
  87.     int sr;
  88.     char *sp;
  89.     char **kvecs;
  90.     int c;
  91.  
  92.     kvecs=(char **)Kbdvbase(); /* this assumes Kbdbase returns the a pointer
  93.                                 * to the actual vectors */
  94.     for(c=0; c<9; c++)
  95.         vecs[c]=kvecs++;
  96.     ssp=Super(0);
  97.     sr=spl7();
  98.     os_base=(*_sysbase)->os_beg;
  99.     gem.xb_old=*(void **)0x88L;
  100.     *(short **)0x88L=&gem.xb_op;
  101.     mytrap.xb_old=*(void **)0x8cL;
  102.     *(short **)0x8cL=&mytrap.xb_op;
  103.     bios.xb_old=*(void **)0xb4L;
  104.     *(short **)0xb4L=&bios.xb_op;
  105.     /* find apid0_appl */
  106.     apid0_appl=aes_appl;
  107.     while(apid0_appl->apid!=0 && apid0_appl->next)
  108.         apid0_appl=apid0_appl->next;
  109.     if(apid0_appl->apid!=0)
  110.     {
  111.          ALERT("could not find apid 0");
  112.          apid0_appl=NULL;
  113.     }else{
  114.          DEBUG("apid 0 application structure at %lx", apid0_appl);
  115.          apid0_save=(struct save_area *)apid0_appl->save_area;
  116.          yield_aes=*(((void(**)())apid0_save->g_ssp) - 1);
  117.     }
  118.     lapps[0]->istk=desk_stk;
  119.     if(!strncmp (apid0_appl->name, "        ", 8))
  120.     {
  121.         /* at startup, anything will look like the desktop */
  122.         DEBUG("lack: apid 0 is desktop");
  123.         is_desk=TRUE;
  124.         sp=(char *)apid0_save->g_ssp;
  125.         if(*sp==0 || *longframe)
  126.         /* if it isn't a 030, it can't have an address with the top
  127.          * byte set, so this test for linef works */
  128.         {
  129.             lapps[0]->pc=*(void(**))sp;
  130.             *(void(**))sp=_desk_leave_aes;
  131.             aes_version=0x160;  /* will be reset by lackcontrol's appl_init */
  132.             DEBUG("tos >= 1.6");
  133.         }else{
  134.         lapps[0]->pc=*(void(**))(sp + 2);
  135.         *(void(**))(sp + 2)=_desk_leave_aes;
  136.             aes_version=0x140;  /* will be reset by lackcontrol's appl_init */
  137.         DEBUG("tos < 1.6");
  138.         }
  139.     }else{
  140.         DEBUG("lack: apid 0 is not desktop");
  141.         first=TRUE;
  142.         sp=(char *)apid0_save->u_ssp;
  143.         if(*longframe)
  144.         {
  145.             lapps[0]->pc=*(void(**))(sp + 4);
  146.             *(void (**))(sp + 4)=_first_leave_aes;
  147.         }else{
  148.             lapps[0]->pc=*(void(**))(sp + 2);
  149.             *(void(**))(sp + 2)=_first_leave_aes;
  150.         }
  151.         lapps[0]->in_aes=1;
  152.     }DEBUG("changing pc %lx on stack %lx", lapps[0]->pc, sp);
  153.     spl(sr);
  154.     Super(ssp);
  155. }
  156.  
  157. void
  158. get_gem_stack()
  159. {
  160.     /* acc user and gem ssp's are on the same stack.  The acc needs to
  161.      * return from Dcntl(LA_INIT_ACC) while it's gem stack is in use.
  162.      * So, we change the gem stack so the acc's ssp can be used for
  163.      * Dcntl(LA_WAKE_APP) when it is time to return to the caller pid.
  164.      * For the first acc, it needs to call Dcntl(LA_WAKE_APP) when gem
  165.      * pid 0 is running, but MiNT lackontrol proccess is active, that
  166.      * is, when apid 0 returns from the trap 2 call made by lackontrol.
  167.      * I hope this makes some sense.
  168.      */
  169.     struct save_area *my_save;
  170.     char *my_gem_stack;
  171.     long ssp; int sr;
  172.  
  173.     my_gem_stack=(char *)Mxalloc(4096, M_PROT_S | M_ALT);
  174.     curapp->mystk_base = curapp->mystk = (long)my_gem_stack+4096;
  175.     my_gem_stack+=2048;
  176.     ssp=Super(0);
  177.     sr=spl7();
  178.     my_save=aes_appl->save_area;
  179.     DEBUG("changing gem's ssp from %lx to %lx", my_save->g_ssp, my_gem_stack);
  180.     my_save->g_ssp=my_gem_stack;
  181.     spl(sr);
  182.     Super(ssp);
  183. }
  184.  
  185. int
  186. check_for_desk(int was_desk)
  187. {
  188.     char *sp;
  189.     
  190.     if(!strncmp(apid0_appl->name, "        ", 8))
  191.     {
  192.     /* Make sure apid 0 is still the desktop */
  193.         sp=(char *)apid0_save->g_ssp;
  194.         if(aes_version > 0x140) /* notice that this differs from the rom rev */
  195.         {
  196.         /* save the pc of desktop and make it return to me, so I can 
  197.          * adjust the MiNT pid, etc.  I figure the desktop call the
  198.          * aes function dipatcher via line-f or jsr, (depending on wether
  199.          * there is such a thing as line-f).
  200.          */
  201.           if (*(void(**))sp!=_desk_leave_aes)
  202.           {
  203.             lapps[0]->pc=*(void(**))sp;
  204.             *(void(**))sp=_desk_leave_aes;
  205.             DEBUG("changed pc %lx on stack %lx", lapps[0]->pc, sp);
  206.           }
  207.         }else{
  208.           if(*(void(**))((char *)sp+2)!=_desk_leave_aes)
  209.           {
  210.         lapps[0]->pc=*(void(**))((char *)sp+2);
  211.         *(void(**))((char *)sp+2)=_desk_leave_aes;
  212.         DEBUG("changed pc %lx on stack %lx", lapps[0]->pc, sp);
  213.           }
  214.         }
  215.         lapps[0]->in_aes=1;
  216.         if (!was_desk) lapps[0]->istk=desk_stk;
  217.     }else{
  218.         is_desk=FALSE;
  219.         if(was_desk) /* desktop has done wind_new */ desk_zap_windows();
  220.         else /* an application has exited, but the desktop didn't
  221.           * wake up. */
  222.          DEBUG("not desktop");
  223.     }
  224. }
  225.  
  226. void
  227. print_global(AESP *call)
  228. {
  229.     char line[80];
  230.     int last=0;
  231.     int count, *global=call->global;
  232.  
  233.     DEBUG("global array from call %d", call->control[0]);
  234.     for(count=0; count<15; count++)
  235.     {
  236.         ksprintf(&line[last], "%x, ", global[count]);
  237.         last=strlen(line);
  238.         if(last>73)
  239.         {
  240.             DEBUG(line);
  241.             last=0;
  242.         }
  243.     }
  244.     if(last) DEBUG(line);
  245. }
  246.  
  247. int
  248. unload()
  249. {
  250.     /* this is called by handle_action during entry to or exit from aes */
  251.     /* we certainly are putting alot of stuff on someone else's stack */
  252.     AESP *old=_aesparams;
  253.     int (*oldcall)()=__aes__;
  254.     NEW_AESP(a);
  255.     BASEPAGE *b=curapp->acc->base;
  256.     char *start=b->p_tbase;
  257.     char *end